//
// Created by songpingwang on 25-7-8.
//

#ifndef UDATAFRAME_H
#define UDATAFRAME_H
#include "UDataBase.h"
#include <string_view>


namespace NDFrame {
    class UDataView;

    class UFrame_API UDataFrame final : public UDataBase {
    public:
        using VecItemPtr = std::vector<DataItem *>;


        UDataFrame() = default;

        explicit UDataFrame(const size_t capacity) {
            this->m_capacity = capacity;
            allocate(capacity);
        }

        UDataFrame(const std::initializer_list<DataItem> items) {
            this->m_size = items.size();
            this->m_capacity = this->m_size;
            allocate(this->m_capacity);
            std::copy(items.begin(), items.end(), this->ItemPtr.get());
        }

        UDataFrame(
            const int idx,
            const int x0, const int y0,
            const int x1, const int y1,
            const int width, const int height,
            const int page, const int flags,
            std::string &&text, std::string &&text_sep) {
            this->m_size = 1;
            this->m_capacity = 1;
            allocate(this->m_capacity);
            this->ItemPtr.get()[0] = DataItem(
                idx, x0, y0, x1, y1,
                width, height, page, flags,
                std::move(text), std::move(text_sep));
        }


        UDataFrame(const UDataFrame &other) : m_size(other.m_size), m_capacity(other.m_capacity), ItemPtr(nullptr) {
            if (m_capacity > 0) {
                allocate(m_capacity);
                std::copy_n(other.ItemPtr.get(), m_size, this->ItemPtr.get());
            }
        }

        void swap(UDataFrame &other) noexcept {
            std::swap(this->m_size, other.m_size);
            std::swap(this->m_capacity, other.m_capacity);
            std::swap(this->ItemPtr, other.ItemPtr);
        }

        /* 移动构造函数 */
        UDataFrame(UDataFrame &&other) noexcept {
            this->ItemPtr = std::move(other.ItemPtr);
            this->m_size = other.m_size;
            this->m_capacity = other.m_capacity;
            other.m_size = 0;
            other.m_capacity = 0;
        }

        ~UDataFrame() override { deallocate(); }

        /* 复制赋值运算符 */
        UDataFrame &operator=(const UDataFrame &other) {
            if (this != &other) {
                UDataFrame temp(other);
                swap(temp);
            }
            return *this;
        }

        /* 移动赋值运算符 */
        UDataFrame &operator=(UDataFrame &&other) noexcept {
            if (this != &other) {
                swap(other);
                other.m_size = 0;
                other.m_capacity = 0;
                other.ItemPtr.reset();
            }
            return *this;
        }

        MAYBE_USE UDataFrame clone() const { return UDataFrame{*this}; } /* 克隆函数      */
        MAYBE_USE size_t size() const override { return this->m_size; }
        VOID_USE void clear() {
            if (this->ItemPtr) {
                std::fill_n(this->ItemPtr.get(), this->m_size, DataItem{});
            }
            this->m_size = 0;
        }

        VOID_USE void set_size(const size_t size) { this->m_size = size; }

        MAYBE_USE bool empty() const override { return this->m_size == 0; }

        MAYBE_USE DataItem *getItemPtr() const override { return this->ItemPtr.get(); }

        MAYBE_USE size_t capacity() const { return this->m_capacity; }

        VOID_USE void push_back(const DataItem &item) {
            if (this->m_size == this->m_capacity) {
                reserve(this->m_capacity == 0 ? 1 : this->m_capacity * 2);
            }
            this->ItemPtr.get()[this->m_size++] = item;
        }

        VOID_USE void push_back(DataItem &&item) {
            if (this->m_size == this->m_capacity) {
                reserve(this->m_capacity == 0 ? 1 : this->m_capacity * 2);
            }
            this->ItemPtr.get()[this->m_size++] = std::move(item);
        }

        const DataItem &operator[](const size_t index) const {
            if (index >= this->m_size) {
                throw std::out_of_range("Index out of range");
            }
            return this->ItemPtr.get()[index];
        }

        DataItem &operator[](const size_t index) {
            if (index >= this->m_size) {
                throw std::out_of_range("Index out of range");
            }
            return this->ItemPtr.get()[index];
        }

        template<Field field>
        auto &ix(const size_t row) {
            if (row >= m_size) {
                throw std::out_of_range("Row index out of range");
            }
            return ItemPtr.get()[row].ValueField<field>();
        }

        template<Field field>
        const auto &ix(const size_t row) const {
            if (row >= m_size) {
                throw std::out_of_range("Row index out of range");
            }
            return ItemPtr.get()[row].ValueField<field>();
        }

        /*bool check_charset();*/

        void reserve(size_t new_capacity);

        DataItem &back() override {
            if (this->empty()) {
                throw std::out_of_range("UDataFrame is empty");
            }
            return this->ItemPtr.get()[this->m_size - 1];
        }

        DataItem &front() override {
            if (this->empty()) {
                throw std::out_of_range("UDataFrame is empty");
            }
            return this->ItemPtr.get()[0];
        }

        VOID_USE void print() const override {
            format_print(*this);
        }

    private:
        size_t m_size = 0;
        size_t m_capacity = 0;
        std::shared_ptr<DataItem[]> ItemPtr;

        void allocate(const size_t new_capacity) {
            this->ItemPtr = std::shared_ptr<DataItem[]>(new DataItem[new_capacity], std::default_delete<DataItem[]>());
            this->m_capacity = new_capacity;
        }

        void deallocate() {
            this->ItemPtr.reset();
            this->m_size = 0;
            this->m_capacity = 0;
        }

    public:
        /*
        *  sort_values 依据提供的字段对整个UDataFrame进行排序
        */
        template<Field field>
        void sort(bool descending = false);

        template<Field field>
        VOID_USE void sub(int num) noexcept;

        template<Field field>
        VOID_USE void add(int num, int max_num) noexcept;

        template<Field field>
        MAYBE_USE float mean_col() const;

        template<Field field>
        MAYBE_USE size_t max_col() const;

        template<Field field>
        MAYBE_USE size_t min_col() const;

        template<Field field>
        MAYBE_USE std::vector<size_t> len() const;

        template<Field field, typename T>
        MAYBE_USE std::vector<std::reference_wrapper<T> > values_ref() const;

        template<Field field, typename T>
        MAYBE_USE std::vector<T> values() const;

        /*
        *  merge_line    对UDataFrame进行合并行
        *  合并条件：      限定宽(width)与高(height)， （下一行的x0与本行的x1的绝对距离小于width)，(下一行的y0与本行的y0的绝对距离小于height)
        *  符合合并条件的： 将本行与下一行text使用sep字符进行合并，(x0,y0)取这两行最小值,(x1,y1,height)取这两行最小大值, 并删除下一行
        */
        MAYBE_USE UDataFrame DF_merge_line(int width, int height, std::string_view sep);


        /**
        * 一般对筛选的子UDataFrame进行重置index
        * reset_index()       直接对整个UDataFrame进行重置索引（无复制）
        */
        VOID_USE void reset_index() noexcept;

        /**
        * DF_pointers_to_df(VecItemPtr& pointers)创建一个由提供指针的新UDataFrame(深复制)
        */
        MAYBE_USE UDataFrame DF_pointers_to_df(const VecItemPtr &pointers) const;

        /**
        * DF_drop_pointer 删除 std::vector<DataItem*>& pointers其中的指针,返回删除后的UDataFrame(深复制)
        * drop_pointer    删除 std::vector<DataItem*>& pointers其中的指针,就地删除
        */
        MAYBE_USE UDataFrame DF_drop_pointer(const VecItemPtr &pointers) const;

        VOID_USE void drop_pointer(const VecItemPtr &pointers);

        /**
        *   判断UDataFrame的text字段是否在field字符串集合中
        *   - 返回值：
        *     std::vector<size_t>& indices     返回符合条件的索引
        *     VecItemPtr& pointers 返回符合条件的UDataFrame的行指针
        *     UDataFrame& dataframe            返回符合条件的UDataFrame(深复制)
        */
        template<Field field>
        MAYBE_USE bool is_in(const std::vector<std::string> &texts, VecItemPtr &out_ptrs) const;

        template<Field field>
        MAYBE_USE bool is_in(const std::vector<std::string> &texts, UDataFrame &out_df) const;

        template<Field field>
        MAYBE_USE bool contains_any(const std::vector<std::string> &texts) const;


        MAYBE_USE static UDataFrame concat(const UDataFrame &df1, const UDataFrame &df2);

        /*
        * 仿照python的join函数
        * 默认为空字符串
        * join_replace对UDataFrame的text合并后的字符串中的字符进行替换
        * const std::string& Char_为分隔符
        */
        template<Field field>
        MAYBE_USE std::string join(std::string_view separator) const;

        template<Field field>
        MAYBE_USE std::string join_and_replace(
            char oldChar,
            std::string_view newChars,
            std::string_view separator = "") const;


        /*
        * 对UDataFrame的text中的字符进行替换放到text或者text_sep字段中(源field_src, 目标field_dst)
        * replace_df_text       替换单个字符
        * multi_replace_df_text 替换多个字符
        */

        template<Field field_src, Field field_dst>
        VOID_USE void replace(char oldChar, char newChar);

        template<Field field_src, Field field_dst>
        VOID_USE void replace(char oldChar0, char newChar0, char oldChar1, char newChar1);


        template<Field field_src, Field field_dst, auto pattern>
        void regex_replace(std::string_view rewrite);


        /* 正则提取： 替换为提取到的数据，否则清空数据 */
        template<Field field, auto pattern>
        void regex_extract();

        /* 正则提取： 仅返回提取到的数据 */
        template<Field field, auto pattern>
        MAYBE_USE UDataFrame DF_regex_extract() const;

        /*
        * 对UDataFrame进行过滤（通用函数：传入lambda函数）
        * filter_ptr          返回符合条件的行地址
        * auto filtered_df = df.DF_filter([](const auto& item) { return item.width < 10; });
        */
        template<typename Predicate>
        MAYBE_USE bool filter(VecItemPtr &out_pointers, Predicate predicate) const;

        template<typename Predicate>
        MAYBE_USE UDataFrame DF_filter(Predicate predicate) const;


        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入Field：（TEXT,TEXT_SEP）, 以及筛选条件） 返回符合条件的UDataFrame(深复制)
        * loc_regex                 返回符合条件的UDataFrame
        * loc_[regex,_xyxy]         返回符合条件的UDataFrame, 筛选条件[regex, (>x0,y0; <x1,y1)]
        * loc_[regex,_x0x1]         返回符合条件的UDataFrame, 筛选条件[regex, (>x0; <x1)]
        * loc_[regex,_y0y1]         返回符合条件的UDataFrame, 筛选条件[regex, (>y0; <y1)]
        * loc_[regex,_x0y0]         返回符合条件的UDataFrame, 筛选条件[regex, (<x0; <y0)]
        * loc_[regex,_x1y1]         返回符合条件的UDataFrame, 筛选条件[regex, (>x1; >y1)]
        */

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex() const {
            return DF_regex_match<field, patterns...>();
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_grate(const int len) const {
            return DF_strlen_impl<field>(len, std::greater<>());
        }


        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_less(const int len) const {
            return DF_strlen_impl<field>(len, std::less<>());
        }


        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_equal(const int len) const {
            return DF_strlen_impl<field>(len, std::equal_to<>());
        }


        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_grate(const int len) const {
            return DF_reg_len_cond<field, patterns...>(len, std::greater<>());
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_equal(const int len) const {
            return DF_reg_len_cond<field, patterns...>(len, std::equal_to<>());
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_less(const int len) const {
            return DF_reg_len_cond<field, patterns...>(len, std::less<>());
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame
        DF_loc_regex_xyxy(int x0, int y0, int x1, int y1) const {
            return DF_regex_cond<field, patterns...>(
                [x0, y0, x1, y1](const DataItem &item) noexcept {
                    return item.x0 > x0 && item.x1 < x1 && item.y0 > y0 && item.y1 < y1;
                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_x0x1(int x0, int x1) const {
            return DF_regex_cond<field, patterns...>(
                [x0, x1](const DataItem &item) noexcept {
                    return item.x0 > x0 && item.x1 < x1;
                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_y0y1(int y0, int y1) const {
            return DF_regex_cond<field, patterns...>(
                [y0, y1](const DataItem &item) noexcept {
                    return item.y0 > y0 && item.y1 < y1;
                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_grate(int x0, int y0) const {
            return DF_regex_cond<field, patterns...>(
                [x0, y0](const DataItem &item) noexcept {
                    return item.x0 > x0 && item.y0 > y0;
                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_less(int x0, int y0) const {
            return DF_regex_cond<field, patterns...>(
                [x0, y0](const DataItem &item) noexcept {
                    return item.x0 < x0 && item.y0 < y0;
                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_loc_regex_x1y1_less(int x1, int y1) const {
            return DF_regex_cond<field, patterns...>(
                [x1, y1](const DataItem &item) noexcept {
                    return item.x1 < x1 && item.y1 < y1;
                });
        }

        MAYBE_USE UDataFrame DF_loc_xyxy(int x0, int y0, int x1, int y1) const {
            auto condition = [x0, y0, x1, y1](const DataItem &item) noexcept -> bool {
                return item.x0 > x0 && item.y0 > y0 && item.x1 < x1 && item.y1 < y1;
            };
            return DF_filter(condition);
        }

        MAYBE_USE UDataFrame DF_loc_x0x1(int x0, int x1) const {
            return DF_filter([x0, x1](const DataItem &item) noexcept { return item.x0 > x0 && item.x1 < x1; });
        }

        MAYBE_USE UDataFrame DF_loc_y0y1(int y0, int y1) const {
            return DF_filter([y0, y1](const DataItem &item) noexcept { return item.y0 > y0 && item.y1 < y1; });
        }

        MAYBE_USE UDataFrame DF_loc_x0y0(int x0, int y0) const {
            return DF_filter([x0, y0](const DataItem &item) noexcept { return item.x0 > x0 && item.y0 > y0; });
        }

        MAYBE_USE UDataFrame DF_loc_x1y1(int x1, int y1) const {
            return DF_filter([x1, y1](const DataItem &item) noexcept { return item.x1 < x1 && item.y1 < y1; });
        }

        MAYBE_USE UDataFrame DF_loc_x0_less(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.x0 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_y0_less(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.y0 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_x1_less(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.x1 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_y1_less(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.y1 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_x0_grate(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.x0 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_y0_grate(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.y0 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_x1_grate(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.x1 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_y1_grate(int len) const {
            return DF_filter([len](const DataItem &item) noexcept { return item.y1 > len; });
        }


        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入Field：（TEXT,TEXT_SEP）, 以及筛选条件） 返回符合条件的地址
        * loc_regex             返回查找值是否为空, 第一个参数为筛选【DataItem的地址】
        * loc_[regex,_xyxy]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x0,y0; <x1,y1)]
        * loc_[regex,_x0x1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x0; <x1)]
        * loc_[regex,_y0y1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>y0; <y1)]
        * loc_[regex,_x0y0]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (<x0; <y0)]
        * loc_[regex,_x1y1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x1; >y1)]
        */

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex(VecItemPtr &out_ptr) const {
            return ptr_reg_impl<field, patterns...>(out_ptr);
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_grate(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_equal(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_less(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::less<>());
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_strlen_grate(VecItemPtr &out_ptr, const int len) const {
            return ptr_reg_len_cond<field, patterns...>(out_ptr, len, std::greater<>());
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_strlen_equal(VecItemPtr &out_ptr, const int len) const {
            return ptr_reg_len_cond<field, patterns...>(out_ptr, len, std::equal_to<>());
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_strlen_less(VecItemPtr &out_ptr, const int len) const {
            return ptr_reg_len_cond<field, patterns...>(out_ptr, len, std::less<>());
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_xyxy(VecItemPtr &out_ptr,
                                      int x0, int y0, int x1, int y1) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [x0, y0, x1, y1](const DataItem &item) noexcept {
                                                    return item.x0 > x0 && item.x1 < x1 && item.y0 > y0 && item.y1 < y1;
                                                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0_less(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.x0 < len;
                                                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0_grate(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.x0 > len;
                                                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_y0_less(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.y0 < len;
                                                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_y0_grate(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.y0 > len;
                                                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x1_less(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.x1 < len;
                                                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x1_grate(VecItemPtr &out_ptr, int len) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [len](const DataItem &item) noexcept {
                                                    return item.x1 > len;
                                                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0_in(VecItemPtr &out_ptr, int x_min, int x_max) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [x_min, x_max](const DataItem &item) noexcept {
                                                    return item.x0 > x_min && item.x0 < x_max;
                                                });
        }


        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_y0_in(VecItemPtr &out_ptr, int y_min, int y_max) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                [y_min, y_max](const DataItem &item) noexcept {
                                                    return item.y0 > y_min && item.y0 < y_max;
                                                });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0x1(VecItemPtr &out_ptr, int x0, int x1) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                    [x0, x1](const DataItem &item) noexcept {
                                                        return item.x0 > x0 && item.x1 < x1;
                                                    });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_y0y1(VecItemPtr &out_ptr, int y0, int y1) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                    [y0, y1](const DataItem &item) noexcept {
                                                        return item.y0 > y0 && item.y1 < y1;
                                                    });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0y0_grate(VecItemPtr &out_ptr, int x0, int y0) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                    [x0, y0](const DataItem &item) noexcept {
                                                        return item.x0 > x0 && item.y0 > y0;
                                                    });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x0y0_less(VecItemPtr &out_ptr, int x0, int y0) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                    [x0, y0](const DataItem &item) noexcept {
                                                        return item.x0 < x0 && item.y0 < y0;
                                                    });
        }

        template<Field field, auto... patterns>
        MAYBE_USE bool loc_regex_x1y1_less(VecItemPtr &out_ptr, int x1, int y1) const {
            return ptr_reg_cond<field, patterns...>(out_ptr,
                                                    [x1, y1](const DataItem &item) noexcept {
                                                        return item.x1 < x1 && item.y1 < y1;
                                                    });
        }

        MAYBE_USE bool loc_xyxy(VecItemPtr &out_ptr, int x0, int y0, int x1, int y1) const {
            auto condition = [x0, y0, x1, y1](const DataItem &item) noexcept -> bool {
                return item.x0 > x0 && item.y0 > y0 && item.x1 < x1 && item.y1 < y1;
            };
            return this->filter(out_ptr, condition);
        }

        MAYBE_USE bool loc_x0x1(VecItemPtr &out_ptr, int x0, int x1) const {
            return this->filter(out_ptr, [x0, x1](const DataItem &item) noexcept {
                return item.x0 > x0 && item.x1 < x1;
            });
        }

        MAYBE_USE bool loc_x0_in(VecItemPtr &out_ptr, int x_min, int x_max) const {
            return this->filter(out_ptr, [x_min, x_max](const DataItem &item) noexcept {
                return item.x0 > x_min && item.x0 < x_max;
            });
        }

        MAYBE_USE bool loc_y0_in(VecItemPtr &out_ptr, int y_min, int y_max) const {
            return this->filter(out_ptr, [y_min, y_max](const DataItem &item) noexcept {
                return item.y0 > y_min && item.y0 < y_max;
            });
        }

        MAYBE_USE bool loc_y0y1(VecItemPtr &out_ptr, int y0, int y1) const {
            return this->filter(out_ptr, [y0, y1](const DataItem &item) noexcept {
                return item.y0 > y0 && item.y1 < y1;
            });
        }

        MAYBE_USE bool loc_x0y0(VecItemPtr &out_ptr, int x0, int y0) const {
            return this->filter(out_ptr, [x0, y0](const DataItem &item) noexcept {
                return item.x0 > x0 && item.y0 > y0;
            });
        }

        MAYBE_USE bool loc_x1y1(VecItemPtr &out_ptr, int x1, int y1) const {
            return this->filter(out_ptr, [x1, y1](const DataItem &item) noexcept {
                return item.x1 < x1 && item.y1 < y1;
            });
        }

        MAYBE_USE bool loc_x0_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x0 < len; });
        }


        MAYBE_USE bool loc_x0_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x0 > len; });
        }

        MAYBE_USE bool loc_y0_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y0 < len; });
        }


        MAYBE_USE bool loc_y0_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y0 > len; });
        }

        MAYBE_USE bool loc_x1_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x1 < len; });
        }

        MAYBE_USE bool loc_x1_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x1 > len; });
        }

        MAYBE_USE bool loc_y1_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y1 < len; });
        }

        MAYBE_USE bool loc_y1_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y1 > len; });
        }

        /*
        * 对UDataFrame  进行索引筛选(默认索引按顺序排列)
        * DF_iloc       返回符合条件的行索引[0,2)的复制UDataFrame类,前闭后开
        * DV_iloc       返回符合条件的行索引[0,2)的视图UDataView类,前闭后开
        * iloc          返回符合条件的行地址[0,2),前闭后开
        */
        MAYBE_USE UDataFrame DF_iloc(int idx0, int idx1) const;

        MAYBE_USE UDataView DV_iloc(int idx0, int idx1) const;

        MAYBE_USE bool iloc(VecItemPtr &out_ptr, int idx0, int idx1) const;

        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入具体数值）
        * - 输入 Field field_
        * - 输入 const VecRegex& regex_, int x0, int y0, int x1, int y1
        * - 返回值(符合条件的视图)：UDataView
        */
        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex() const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_strlen_grate(int len) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_strlen_equal(int len) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_strlen_less(int len) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_xyxy(int x0, int y0, int x1, int y1) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_x0x1(int x0, int x1) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_y0y1(int y0, int y1) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_x0y0_grate(int x0, int y0) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_x0y0_less(int x0, int y0) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView DV_loc_regex_x1y1(int x1, int y1) const;

        MAYBE_USE UDataView DV_loc_xyxy(int x0, int y0, int x1, int y1) const;

        MAYBE_USE UDataView DV_loc_x0x1(int x0, int x1) const;

        MAYBE_USE UDataView DV_loc_y0y1(int y0, int y1) const;

        MAYBE_USE UDataView DV_loc_x0y0_grate(int x0, int y0) const;

        MAYBE_USE UDataView DV_loc_x0y0_less(int x0, int y0) const;

        MAYBE_USE UDataView DV_loc_x1y1_less(int x1, int y1) const;

        MAYBE_USE UDataView DV_loc_x0_grate(int x0) const;

        MAYBE_USE UDataView DV_loc_x0_less(int x0) const;

        MAYBE_USE UDataView DV_loc_x1_less(int x1) const;

        MAYBE_USE UDataView DV_loc_y0_grate(int y0) const;

        MAYBE_USE UDataView DV_loc_y0_less(int y0) const;

        MAYBE_USE UDataView DV_loc_y1_less(int y1) const;

    private:
        template<Field field>
        bool contains_impl(
            const std::unordered_set<std::string> &text_set,
            VecItemPtr *out_ptrs = nullptr,
            UDataFrame *out_df = nullptr) const;

        /////////////////////////////////////////////////////////////////////

        template<Field field, typename Comparator>
        MAYBE_USE static constexpr auto getCompare();

        ////////////////////////////////////////////////////////////////////////////////////////////////////
        template<Field field, auto... patterns>
        MAYBE_USE UDataFrame DF_regex_match() const;


        template<Field field, auto... patterns, typename Comparator>
        UDataFrame DF_reg_len_cond(size_t len, Comparator compare) const;

        template<Field field, typename Comparator>
        MAYBE_USE UDataFrame DF_strlen_impl(size_t len, Comparator compare) const;

        template<Field field, auto... patterns, typename Predicate>
        MAYBE_USE UDataFrame DF_regex_cond(Predicate predicate) const;

        //////////////////////////////////////////////////////////////////
        template<Field field, auto... patterns>
        bool ptr_reg_impl(VecItemPtr &out_ptr) const;

        template<Field field, auto... patterns, typename Comparator>
        bool ptr_reg_len_cond(VecItemPtr &out_ptr, size_t len, Comparator compare) const;


        template<Field field, typename Comparator>
        bool ptr_strlen_impl(VecItemPtr &out_ptr, size_t len, Comparator compare) const;

        template<Field field, auto... patterns, typename Predicate>
        bool ptr_reg_cond(VecItemPtr& out_ptr,  Predicate predicate) const;

        //////////////////////////////////////////////////////////////////
        template<typename ConditionInt>
        MAYBE_USE UDataView DV_loc(ConditionInt conditionInt) const;

        template<Field field, auto... patterns>
        MAYBE_USE UDataView dv_reg_impl() const;

        template<Field field, auto... patterns, typename Predicate>
        MAYBE_USE UDataView dv_reg_len_cond(
            int len, Predicate predicate) const;

        template<Field field, auto... patterns, typename Predicate>
        MAYBE_USE UDataView dv_reg_cond(Predicate predicate) const;
    };
}

#include "UDataFrame.inl"
#endif //UDATAFRAME_H
